package chloroform.json.comp

import chloroform.l10n.ProjectEntrySafeMetaData
import java.util.Locale
import scaladuct.{Property, PropertyValue}
import chloroform.json.{ProjectEntriesBuildContext, JsonBuilderFactory, CookiePropertyProcessingContext, GenericFactoryForElement}
import scaladuct.l10n.{SafeMetaData, HintMeta, PropertyMeta, HasHintsMetaDataSource}
import argo.jdom.JsonRootNode

/**
 * User: zslajchrt
 * Date: 16.5.11
 * Time: 20:10
 */
object Metadata {
  def getConstructors =
    List(new CommonMetaDataConstructor)

def getHintConstructors =
    List(new HintCommonMetaDataConstructor)

def getProjectEntryConstructors =
    List(new ProjectEntryMetaDataConstructor)
}

class CommonMetaData extends JsonComposite {
  val title = string("")
  val description = string("")
  val icon = string("")
}


class CommonMetaDataHolder extends JsonComposite {
  val CommonMetaData = struct(new CommonMetaData())
}

abstract class AbstractCommonMetaDataConstructor[P <: Property[_]]
  extends GenericFactoryForElement[P, CookiePropertyProcessingContext, JsonBuilderFactory[JsonRootNode]] {

  def createMetaData(source: HasHintsMetaDataSource, property: P, locale: Locale): SafeMetaData

  def create(property: P, ctx: CookiePropertyProcessingContext): Option[JsonBuilderFactory[JsonRootNode]] = {
    ctx.cookieGateway.pageExtension(classOf[scaladuct.l10n.HasHintsMetaDataSource]) match {
      case None => None
      case Some(source) => {
        val mtd = createMetaData(source, property, ctx.locale)
        val commonMetaDataHolder = new CommonMetaDataHolder
        commonMetaDataHolder.CommonMetaData().title <= mtd.title(property.name)
        commonMetaDataHolder.CommonMetaData().description <= mtd.description("")

        Some(commonMetaDataHolder)
      }
    }
  }
}

class CommonMetaDataConstructor extends AbstractCommonMetaDataConstructor[PropertyValue[_]] {
  def createMetaData(source: HasHintsMetaDataSource, property: PropertyValue[_], locale: Locale) = {
    new PropertyMeta(source, locale, property)
  }
}

class HintCommonMetaDataConstructor extends AbstractCommonMetaDataConstructor[Property[Any]] {
  def createMetaData(source: HasHintsMetaDataSource, hint: Property[Any], locale: Locale) = {
    new HintMeta(source, locale, hint)
  }
}

class ProjectEntryMetaDataConstructor
  extends GenericFactoryForElement[chloroform.ProjectEntry, ProjectEntriesBuildContext, JsonBuilderFactory[JsonRootNode]] {
  def create(entry: chloroform.ProjectEntry, ctx: ProjectEntriesBuildContext) = {
    ctx.projectGateway.extension(classOf[chloroform.l10n.ProjectMetaDataSource]) match {
      case None => None
      case Some(source) => {
        val mtd = new ProjectEntrySafeMetaData(source, entry, entry.name, ctx.locale)
        val commonMetaDataHolder = new CommonMetaDataHolder
        commonMetaDataHolder.CommonMetaData().title <= mtd.title.get
        commonMetaDataHolder.CommonMetaData().description <= mtd.description.get

        Some(commonMetaDataHolder)
      }
    }

  }
}
